﻿namespace designpatternsplusplus.decorator.DecoratorParticipants
{
    #region

    using System;
    using System.Collections.ObjectModel;
    using designpatternsplus.contracts;
    using Support;

    #endregion

    /// <summary>
    /// Delegate Function Repository
    /// Indeed a collection of function call
    /// signatures
    /// We can store function definitions
    /// just like other data in collections
    /// as we do here
    /// This is preferred to forcing a concrete
    /// class to represent a simple function
    /// as many decorators do
    /// </summary>
    sealed class ItemDelegateRepository : Collection<KeyedDelegate>
    {
        static readonly ItemDelegateRepository _instance;

        static ItemDelegateRepository()
        {
            _instance = new ItemDelegateRepository
                        {
                            new KeyedDelegate("BaseTax", GetBaseTaxDelegate),
                            new KeyedDelegate("ImportTax", GetImportTaxDelegate)
                        };
        }

        static Func<IProductService, double> GetImportTaxDelegate
        {
            get
            {
                const double IMPORT_DUTY = .05;
                return
                    _dec =>
                    FloatingPointService.RoundTaxAmount
                        (_dec.IsImported, IMPORT_DUTY, _dec.BaseAmount);
            }
        }

        static Func<IProductService, double> GetBaseTaxDelegate
        {
            get
            {
                const double BASE_TAX_RATE = .1;
                return
                    _dec =>
                    FloatingPointService.RoundTaxAmount
                        (!_dec.Type.IsTaxExempt, BASE_TAX_RATE, _dec.BaseAmount);
            }
        }

        public static ItemDelegateRepository Functions
        {
            get { return _instance; }
        }
    }
}